package com.jd.ssdb4j.stream.impl;

import com.jd.ssdb4j.base.Response;
import com.jd.ssdb4j.exception.SSDBConnectionException;
import com.jd.ssdb4j.stream.AbstractSSDBStream;
import com.jd.ssdb4j.stream.MemoryStream;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;

public class SocketSSDBStream extends AbstractSSDBStream {

    private String host;
    private int port;
    private int timeout;

	public SocketSSDBStream(String host, int port, int timeout) {

        try {

            socket = new Socket(host, port);
            if(timeout > 0){
                socket.setSoTimeout(timeout);
            }
            socket.setTcpNoDelay(true);

            this.host = host;
            this.port = port;
            this.timeout = timeout;
            this.input = new MemoryStream();

        } catch (Exception e) {

            throw new SSDBConnectionException(e);
        }
	}

	protected void beforeExec() {

		if (!socket.isConnected()) {

            try {

				socket.connect(new InetSocketAddress(host, port));
                if(timeout > 0){
                    socket.setSoTimeout(timeout);
                }
                socket.setTcpNoDelay(true);

                if (input == null) {
                    input = new MemoryStream();
                }
			} catch (IOException e) {
				throw new SSDBConnectionException(e);
			}
		}
	}

	@Override
	protected Response whenError(Throwable e) {
		if (!socket.isClosed())
			try {
				socket.close();
			} catch (IOException e1) {
				e1.printStackTrace();
			}
		return super.whenError(e);
	}

	protected void finalize() throws Throwable {
		if (socket != null && !socket.isClosed())
			socket.close();
	}
	
	@Override
	public void close() throws Exception {
        if (socket != null && !socket.isClosed())
            socket.close();
	}
}
